from common_import import *
import predict_log_log

l = 0.13
k = 0.7
P_p = 0
Q_p = 0
E_p = 0
C_p = 0
A = 0


def objective_function(x):
    P = x
    Q = Q_p * ((P / P_p) ** E_p)
    result = P * Q * (1 - l + l * k) - Q * C_p
    # print(Q)
    return -result


def get_q(x):
    P = x
    Q = Q_p * ((P / P_p) ** E_p)
    # Q = Q_p + A * (P - P_p)
    return Q


def neighbor_function(x):
    return x + np.random.uniform(-1, 1)


def simulated_annealing(initial_solution):
    """
    使用模拟退火算法求解最优化问题。

    Parameters:
    - objective_function: 目标函数
    - initial_solution: 初始解
    - initial_temp: 初始温度
    - alpha: 温度衰减系数
    - stopping_temp: 停止温度
    - stopping_iter: 最大迭代次数
    - neighbor_function: 用于生成新解的邻域函数

    Returns:
    - best_solution: 最优解
    - best_objective_value: 最优目标函数值
    """
    initial_solution = 10
    initial_temp = 1000
    alpha = 0.9
    stopping_temp = 1e-3
    stopping_iter = 1000
    # 初始化
    current_solution = initial_solution
    current_objective_value = objective_function(current_solution)
    best_solution = current_solution
    best_objective_value = current_objective_value
    current_temp = initial_temp
    iteration = 0

    while current_temp > stopping_temp and iteration < stopping_iter:
        # 生成邻域中的新解
        new_solution = neighbor_function(current_solution)
        new_objective_value = objective_function(new_solution)

        # 计算目标函数差值
        delta_e = new_objective_value - current_objective_value

        # 接受新解的条件
        if delta_e < 0 or np.random.rand() < np.exp(-delta_e / current_temp):
            current_solution = new_solution
            current_objective_value = new_objective_value

            # 如果找到更优解，则更新最优解
            if current_objective_value < best_objective_value:
                best_solution = current_solution
                best_objective_value = current_objective_value

        # 降温
        current_temp *= alpha
        iteration += 1

    return best_solution, -best_objective_value


if __name__ == "__main__":

    # best_solution, best_objective_value = simulated_annealing()

    # print(
    #     f"Best Solution: {best_solution}, Best Objective Value: {best_objective_value}"
    # )
    my_Ep = [0, 8, 5.3, 2.4, 4.5, 5.5, 5.7]
    for ii in range(1, 7):
        data = tool.get_np(f"predict_2/{ii}.csv")
        E_p = (
            predict_log_log.log_log_demand_get_param(tool.get_np(f"problem_2/{ii}.csv"))
            * my_Ep[ii]
        )
        A = predict_log_log.linear_demand_get_param(tool.get_np(f"problem_2/{ii}.csv"))
        dtype = np.dtype(
            [
                ("date", "U10"),  # 日期列，长度为10的字符串
                ("price", "f8"),  # 价格列，float64
                ("quantity", "f8"),  # 数量列，float64
                ("addition", "f8"),  # 附加值列，float64
            ]
        )

        # 初始化结构化数组
        results = np.empty(7, dtype=dtype)

        # 设置初始日期
        start_date = datetime.datetime(2023, 7, 1)
        for i in range(7):
            row = data[i]
            P_p = row["sale_price"]
            C_p = row["cost_price"]
            Q_p = row["total_quantity"]
            ini = P_p
            best_solution, best_objective_value = simulated_annealing(ini)
            price = np.round(best_solution, 2)
            quantity = np.round(get_q(best_solution), 2)
            addition = np.round((price - C_p) / C_p, 4)
            # 填充日期
            results["date"][i] = (start_date + datetime.timedelta(days=i)).strftime(
                "%Y-%m-%d"
            )
            # 填充价格、数量和附加值
            results["price"][i] = price
            results["quantity"][i] = quantity
            results["addition"][i] = addition
        print(results)
        # tool.get_csv(results, f"problem2_result/{ii}.csv")
